using EasyCaching.Core;
using EasyCaching.Core.Configurations;
using EasyCaching.Core.Serialization;
using MessagePack.Resolvers;
using Microsoft.Extensions.Caching.Distributed;
using TK.Common.Cache;

namespace Microsoft.Extensions.DependencyInjection
{
    /// <summary>
    /// easycaching cache接入扩展
    /// </summary>
    public static class EasyCachingCacheExtensions
    {
        /// <summary>
        /// easycaching缓存服务,假如是redis cache,扩展到IDistributedCache; 
        /// 实际的缓存缓存组件，请自行引用，配置使用与easycaching文档一致
        /// </summary>
        public static IServiceCollection AddTKEasyCaching(this IServiceCollection services, Action<EasyCachingOptions> setupAction = null)
        {
            if (setupAction != null)
            {
                services.AddEasyCaching(setupAction);
            }

            services.AddEasyCaching(option =>
            {        
                if (!services.Any(m => m.ServiceType == typeof(IEasyCachingProvider)))
                {
                    option.UseInMemory(memoryOption =>
                    {
                        memoryOption.MaxRdSecond = 0;
                        memoryOption.SerializerName = "msgpack";

                    }, "default_memory");
                }
                
                if (!services.Any(m => m.ServiceType == typeof(IEasyCachingSerializer)))
                {
                    option.WithMessagePack(msgpackOption =>
                    {
                        msgpackOption.EnableCustomResolver = true;
                        msgpackOption.CustomResolvers = CompositeResolver.Create(new MessagePack.IFormatterResolver[]
                        {
                        // This can solve DateTime time zone problem
                        NativeDateTimeResolver.Instance,
                        ContractlessStandardResolver.Instance
                        });
                    }, "msgpack");
                }
            });
            if (!services.Any(m => m.ServiceType == typeof(IDistributedCache)))
            {
                var redisCacheProvider = services.BuildServiceProvider().GetService<IRedisCachingProvider>();
                if (redisCacheProvider != null)
                {
                    // 假如是redis cache，扩展IDistributedCache
                    services.Add(ServiceDescriptor.Singleton<IDistributedCache, EasyCachingRedisCache>());
                }
                else
                {
                    services.Add(ServiceDescriptor.Singleton<IDistributedCache, DefaultEasyCachingCache>());
                }
            }

            return services;
        }
    }
}
